package org.ranch.api.utils;

import java.io.File;
import java.lang.reflect.Field;

import org.apache.commons.lang.StringUtils;
import org.ranch.api.ConceptAnnotation;
import org.ranch.api.ConceptCategoryAnnotation;
import org.ranch.api.RanchConstants;
import org.ranch.model.Gender;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Ranch Utilities.
 * 
 */
public final class RanchUtil {

    /**
     * default constructor. does not allow instantiation
     */
    private RanchUtil() {
	// prevents calls from subclass
	LOG.warn("");
	throw new UnsupportedOperationException();
    }

    /** The logger. */
    private static final Logger LOG = LoggerFactory.getLogger(RanchUtil.class);

    /**
     * Gets the application data directory of mohr for the logged on user.
     * 
     * @return The path to the directory on the file system that will hold
     *         miscellaneous data about the application (runtime properties,
     *         modules, etc)
     */
    public static String getApplicationDataDirectory() {

	String filepath = null;
	if (RanchConstants.OPERATING_SYSTEM_LINUX.equalsIgnoreCase(RanchConstants.OPERATING_SYSTEM)
		|| RanchConstants.OPERATING_SYSTEM_FREEBSD
		.equalsIgnoreCase(RanchConstants.OPERATING_SYSTEM)
		|| RanchConstants.OPERATING_SYSTEM_OSX
		.equalsIgnoreCase(RanchConstants.OPERATING_SYSTEM)) {

	    filepath = System.getProperty("user.home") + File.separator + ".ranch";
	} else {
	    filepath = System.getProperty("user.home") + File.separator + "Application Data"
		    + File.separator + "ranch";
	}

	filepath = filepath + File.separator;

	File folder = new File(filepath);
	if (!folder.exists()) {
	    folder.mkdirs();
	}

	return filepath;
    }

    /**
     * gets the concept category annotation for the given containing class and
     * concept category
     * 
     * @param containingClass
     *            the class containing the field whose concept category
     *            annotation is required
     * @param conceptCategory
     *            the concept category whose concept category annotation is
     *            required
     * @return
     * @throws SecurityException
     *             thrown if we have no access to the field of the containing
     *             class by reflection
     * @throws NoSuchFieldException
     *             thrown if the field doesn't exist in the given containing
     *             class
     */
    public static ConceptCategoryAnnotation getConceptCategoryFieldAnnotation(
	    Class<?> containingClass, String conceptCategory)
	    throws SecurityException, NoSuchFieldException {
	Field[] fields = containingClass.getFields();
	for (Field field : fields) {
	    try {
		String fieldValue = (String) field.get(conceptCategory);
		if (fieldValue != null && StringUtils.equals(fieldValue, conceptCategory)) {
		    return field.getAnnotation(ConceptCategoryAnnotation.class);
		}
	    } catch (IllegalArgumentException e) {
		e.printStackTrace();
	    } catch (IllegalAccessException e) {
		e.printStackTrace();
	    }
	}

	return null;
    }

    /**
     * gets the concept annotation for the given field in the given containing
     * class
     * 
     * @param containingClass
     *            the class containing the field whose concept annotation is
     *            required
     * @param conceptName
     *            the name of the concept whose concept annotation is required.
     * @return
     * @throws SecurityException
     *             thrown if we have no access to the field of the containing
     *             class by reflection
     * @throws NoSuchFieldException
     *             thrown if the field doesn't exist in the given containing
     *             class
     */
    public static ConceptAnnotation getConceptFieldAnnotation(Class<?> containingClass,
	    String conceptName) throws SecurityException, NoSuchFieldException {
	Field[] fields = containingClass.getFields();
	for (Field field : fields) {
	    try {
		String fieldValue = (String) field.get(conceptName);
		if (fieldValue != null && StringUtils.equals(fieldValue, conceptName)) {
		    return field.getAnnotation(ConceptAnnotation.class);
		}
	    } catch (IllegalArgumentException e) {
		e.printStackTrace();
	    } catch (IllegalAccessException e) {
		e.printStackTrace();
	    }
	}

	return null;
    }

    /**
     * gets an array of gender elements
     * 
     * @return Gender[]
     */
    public static Gender[] getGenderList() {
	return new Gender[] { Gender.FEMALE, Gender.MALE, Gender.UNKNOWN };
    }

    /**
     * creates a username for the given staff member
     * 
     * @param first
     *            the first name
     * @param last
     *            the last name
     * @return the created username
     */
    public static String createUsername(String first, String last) {
	String username;
	first = first.toLowerCase();
	last = last.toLowerCase();
	if (last.indexOf(' ') > 0) {
	    username = last
		    .substring(0, last.indexOf(' '));
	} else {
	    username = last;
	}

	if (first.indexOf(' ') > 0) {
	    username += "."
		    + first
		    .substring(0, first.indexOf(' '));
	} else {
	    username += "." + first;
	}
	return username;
    }
}
